﻿using System;
using System.Reflection;
using System.Threading;

namespace CSharp进阶_反射
{
	enum E_Type
	{
		A,
		B,
		C
	}
	class Test
	{
		private int i = 1;
		public int j = 2;
		public string str = "hello world!";
		E_Type ttt = E_Type.B;
		public Test()
		{
		}
		public Test(int i)
		{
			this.i = i;
		}
		public Test(int i, int j) : this(i)
		{
			this.j = j;
		}
		public Test(int i, int j, string str) : this(i, j)
		{
			this.str = str;
		}
		public void Print(int id, string msg)
		{
			Console.WriteLine("id={0}\tmsg={1}", id, msg);
		}
		public void Print()
		{
			Console.WriteLine("i={0}\tj={1}\tstr={2}", i, j, str);
		}
		override public string ToString()
		{
			return string.Format("i={0}\tj={1}\tstr={2}", i, j, str);
		}
	}
	class Program
	{
		static void Main(string[] args)
		{
			//#region 获取Type
			//Console.WriteLine("--------\t获取Type\t--------");
			//// 1.通过GetType()
			//int a = 10;
			//Type type1 = a.GetType();
			//Console.WriteLine(type1);
			//// 2.通过typeof()
			//Type type2 = typeof(int);
			//Console.WriteLine(type2);
			//// 3.通过Type.GetType()
			//Type type3 = Type.GetType("System.Int32");
			//// type1/type2/type3是指向了同一个堆空间
			//Console.WriteLine(type3);
			//#endregion
			//#region 得到类的程序集信息
			//Console.WriteLine("--------\t得到类的程序集信息\t--------");
			//Console.WriteLine(type1.Assembly);
			//Console.WriteLine(type2.Assembly);
			//Console.WriteLine(type3.Assembly);
			//#endregion
			//#region 得到所有公共成员
			//Console.WriteLine("--------\t得到所有公共成员\t--------");
			//Type type = typeof(Test);
			//// 引入命名空间 using System.Reflection;
			//MemberInfo[] memberInfos = type.GetMembers();
			//foreach (MemberInfo memberInfo in memberInfos)
			//{
			//	Console.WriteLine(memberInfo);
			//}
			//Console.WriteLine("\n");
			//memberInfos = type.GetMember("j");
			//foreach (MemberInfo memberInfo in memberInfos)
			//{
			//	Console.WriteLine(memberInfo);
			//}
			//#endregion
			//#region 获取公共构造并调用
			//Console.WriteLine("--------\t获取公共构造并调用\t--------");
			//// 1.获取所有的构造函数
			//ConstructorInfo[] constructors = type.GetConstructors();
			//foreach (ConstructorInfo constructor in constructors)
			//{
			//	Console.WriteLine(constructor);
			//}
			//// 2.获取某一构造
			////得构造函数传入 Type数组 数组中内容按顺序是参数类型
			////执行构造函数传入  object数组 表示按顺序传入的参数
			//ConstructorInfo constructorInfo = type.GetConstructor(new Type[0]);
			//Test test = constructorInfo.Invoke(new object[0]) as Test;
			//Console.WriteLine(test);

			//constructorInfo = type.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(string) });
			//test = constructorInfo.Invoke(new object[] { 100, 50, "miku best" }) as Test;
			//Console.WriteLine(test);
			//#endregion
			//#region 获取类的公共成员变量
			//Console.WriteLine("--------\t获取类的公共成员变量\t--------");
			//// 1.得到所有公共成员变量
			//FieldInfo[] fields = type.GetFields();
			//foreach (FieldInfo field in fields)
			//{
			//	Console.WriteLine(field);
			//}
			//// 2.得到指定公共成员变量
			//FieldInfo fieldInfo = type.GetField("str");
			//Console.WriteLine(fieldInfo);
			//Console.WriteLine(fieldInfo.GetValue(test));
			//fieldInfo.SetValue(test, "i like miku very much");
			//Console.WriteLine(fieldInfo.GetValue(test));
			//#endregion
			//#region 获取类的公共成员方法
			//Console.WriteLine("--------\t获取类的公共成员方法\t--------");
			//// 1.获取所有公共成员方法
			//MethodInfo[] methods = type.GetMethods();
			//foreach (MethodInfo method in methods)
			//{
			//	Console.WriteLine(method);
			//}
			//// 2.获取指定公共成员方法
			//MethodInfo methodInfo = type.GetMethod("ToString");
			//Console.WriteLine(methodInfo);
			//string res = methodInfo.Invoke(test, null) as string;
			//Console.WriteLine(res);

			//methodInfo = type.GetMethod("Print", new Type[] { typeof(int), typeof(string) });
			//Console.WriteLine(methodInfo);
			//methodInfo.Invoke(test, new object[] { 1001, "warning, the msg already running!"});
			//#endregion
			//#region 枚举
			//Console.WriteLine("--------\t枚举\t--------");
			//type = typeof(E_Type);
			//string [] enumInfos = type.GetEnumNames();
			//foreach (string enumInfot in enumInfos)
			//{
			//	Console.WriteLine(enumInfot);
			//}
			//string enumInfo = type.GetEnumName(1);
			//Console.WriteLine(enumInfo);

			//Array array = type.GetEnumValues();
			//foreach (object obj in array)
			//{
			//	Console.WriteLine(obj + " " + (E_Type)obj);
			//}
			//#endregion
			//#region 事件
			//Console.WriteLine("--------\t事件\t--------");
			//#endregion
			//#region 属性
			//type.GetProperties();
			//#endregion
			//#region 接口
			//type.GetInterfaces();
			//#endregion
			//#region Activator
			//Console.WriteLine("--------\tActivator\t--------");
			//Type t = typeof(Test);
			//object obj1 = Activator.CreateInstance(t);
			//object obj2 = Activator.CreateInstance(t, 100);
			//object obj3 = Activator.CreateInstance(t, 100, 200);
			//object obj4 = Activator.CreateInstance(t, 100, 200, "miku dance");
			//MethodInfo tostring = t.GetMethod("Print", new Type[0]);
			//tostring.Invoke(obj1, null);
			//tostring.Invoke(obj2, null);
			//tostring.Invoke(obj3, null);
			//tostring.Invoke(obj4, null);
			//#endregion
			#region Assembly类
			 Console.WriteLine("--------\tAssembly类\t--------");
			// 1.加载制定程序集
			//Assembly assemble = Assembly.Load("System.Data");
			Assembly assembly = 
				Assembly.LoadFrom(@"D:\code\game-develop-mini\CSharp\CSharp进阶\CSharp进阶_多线程\bin\Debug\net5.0\CSharp进阶_多线程");
			Type[] types = assembly.GetTypes();
			//foreach (Type ty in types)
			//{
			//	Console.WriteLine(ty);
			//}
			// 2.加载程序集中的一个类对象
			Type icon = assembly.GetType("CSharp进阶_多线程.Program+Icon");
			MemberInfo[] memInfos = icon.GetMembers();
			//foreach (MemberInfo memInfo in memInfos)
			//{
			//	Console.WriteLine(memInfo);
			//}
			Type enumType = assembly.GetType("CSharp进阶_多线程.Program+E_MoveDirection");
			FieldInfo enumFieldInfo = enumType.GetField("Left");
			object iconObj = Activator.CreateInstance(icon, 10, 10, enumFieldInfo.GetValue(null));

			MethodInfo show = icon.GetMethod("Show", new Type[0]);
			MethodInfo Hide = icon.GetMethod("Hide", new Type[0]);
			MethodInfo move = icon.GetMethod("Move", new Type[0]);
			MethodInfo changeDir = icon.GetMethod("ChangeDirection", new Type[] { enumType });
			bool isRunning = true;
			Thread thread = new Thread(() =>
			{
				while (isRunning)
				{
					switch (Console.ReadKey(true).Key)
					{
						case ConsoleKey.W:
							changeDir.Invoke(iconObj, new object[] { enumType.GetField("Up").GetValue(null) });
							break;
						case ConsoleKey.A:
							changeDir.Invoke(iconObj, new object[] { enumType.GetField("Left").GetValue(null) });
							break;
						case ConsoleKey.D:
							changeDir.Invoke(iconObj, new object[] { enumType.GetField("Right").GetValue(null) });
							break;
						case ConsoleKey.S:
							changeDir.Invoke(iconObj,new object[] { enumType.GetField("Down").GetValue(null) });
							break;
					}
				}
				Console.WriteLine("thread {0} exit", Thread.GetCurrentProcessorId());
			});
			thread.IsBackground = true;
			thread.Start();
			Console.Clear();
			Console.CursorVisible = false;
			int count = 0;
			while (true)
			{
				Hide.Invoke(iconObj, null);
				show.Invoke(iconObj, null);
				move.Invoke(iconObj, null);
				Thread.Sleep(1000);
				count++;
				if (count > 500)
				{
					isRunning = false;
					break;
				}
			}
			thread.Join();
			#endregion
			#region 类库的创建
			#endregion
		}
	}
}
